<?php

namespace App\Http\Controllers\DingAttendanceStatus;

use App\Http\Controllers\Controller;
use App\Models\Attendance\Attendance;
use App\Models\Attendance\AttendanceData;
use App\Models\Bus\BusDistribution;
use App\Models\Role;
use App\Models\Attendance\AttendanceCollect;
use App\Models\Dict;
use App\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class DingAttendanceStatusController extends Controller
{
    public $roleId;
    public $roleName;
    public $userId;
    public $userName;
    public $jobTitle;

    public function getSeeIds($userId): void
    {
        if ($userId) {
            $userInfo = User::query()->where('ding_user_id', $userId)->first();
            if ($userInfo) {
                $this->roleId = $userInfo['group_id'];
                $job_title_array = Dict::getOptionsByName('职位');
                foreach ($job_title_array as $value) {
                    if ($value['value'] == $userInfo['office']) {
                        $job_title = $value['title'];
                        $this->jobTitle = mb_substr($job_title, 0, -1);
                    }
                }
                // $this->roleName = Role::query()->where('id', $userInfo['group_id'])->first()->name;
                $roleId = DB::table('sys_roles_users')->where('user_id', $userInfo['id'])->pluck('role_id')->toArray();
                $this->roleName = Role::query()->whereIn('id', $roleId)->pluck('name')->toArray();
                $this->userId = $userInfo['id'];
                $this->userName = $userInfo['name'];
            }
        }
    }
    /**
     * 获取列表数据
     *
     * @param  Request  $request
     *
     * @return mixed
     */
    public function attendanceStatusList(Request $request)
    {
        $params = $request->all();
        $this->getSeeIds($params['ding_user_id']);
        if (isset($params['date'])) {
            $params['date'] = date('Y-m-d', strtotime($params['date']));
        } else {
            //如果没有查询日期,就查询打卡记录最后日期记录
            $sign_date = AttendanceCollect::query()
                ->groupBy('sign_date')
                ->orderByDesc('sign_date')
                ->first()
                ->sign_date;
            $params['date'] = date('Y-m-d', strtotime($sign_date));
        }
        //因为存在没有打卡的情况列表需要展示此车队长下所有车牌号
        //获取所有车队
        $job_array =  ['一车队', '二车队', '三车队'];
        if (in_array($this->jobTitle, $job_array)) {
            $busQuery =  BusDistribution::query()
                ->where('team', $this->jobTitle)
                ->where('date', '<=', $params['date'])
                ->where('end_date', '>=', $params['date']);
            if (isset($params['license_plate_num'])) {
                $busQuery->where('license_plate_num', $params['license_plate_num']);
            }
            if (isset($params['line']) && $params['line'] != '-1') {
                $busQuery->where('line', $params['line']);
            }
            $busNumber = $busQuery->orderBy('license_plate_num')
                ->groupBy('license_plate_num')
                ->pluck('line', 'license_plate_num')
                ->toArray();
        } else {
            return response()->formatJson('', '抱歉您不是车队长没有修改权限');
        }
        //判断要查询的车辆是否在管理权限之内
        if (empty($busNumber)) {
            return response()->formatJson('', '抱歉您没有管理此辆车辆的权限');
        }
        $busNumberArray = array_keys($busNumber);
        $query = $this->getQuery($params);
        $data = $query->whereIn('license_plate_num', $busNumberArray)
            ->orderBy('line')
            ->orderBy('license_plate_num')
            ->get();
        $data = collect($data)->groupBy('license_plate_num')->toArray();
        $post_data = [];
        foreach ($busNumber as $key => $v) {
            $post_data[$key]['drivers'] = isset($data[$key]) ? $data[$key] : [];
            $post_data[$key]['license_plate_num'] = $key;
            $post_data[$key]['line'] = $v;
        }
        $result = [
            'license_plate_num' => isset($params['license_plate_num']) ? $params['license_plate_num'] : '',
            'date' => $params['date'],
            'line' => isset($params['line']) ? $params['line'] : '-1',
            'record' => $post_data,
        ];
        return response()->formatJson($result);
    }
    /**
     * 根据查询条件拼接sql语句
     *
     * @param [array] $params
     * @return Builder
     */
    public function getQuery($params): Builder
    {
        $query = AttendanceCollect::query()
            ->where('sign_date', $params['date']);
        if (isset($params['license_plate_num'])) {
            $query->where('license_plate_num', 'like', '%' . $params['license_plate_num'] . '%');
        }
        if (isset($params['driver'])) {
            $query->where('driver', 'like', '%' . $params['driver'] . '%');
        }
        if (isset($params['line']) && -1 != $params['line']) {
            $query->where('line', $params['line']);
        }
        return $query;
    }
    /**
     * 根据车牌号,线路,日期返回车辆考勤汇总数据
     *
     * @param Request $request
     * @return void
     */
    public function busDetailData(Request $request)
    {
        $params = $request->all();
        $query = $this->getQuery($params);
        $data = $query->orderBy('line')->orderBy('driver')->get()->toArray();
        //获取车辆当天考勤汇总数据
        $busData = DB::table('akbus_bus_attendance_collect')
            ->where('signDate', $params['date'])
            ->where('busNumber', $params['license_plate_num'])
            ->where('line', $params['line'])
            ->where('is_del', 0)
            ->get()
            ->toArray();
        $result = [
            'lists' => $data,
            'busData' => $busData,
        ];
        return response()->formatJson($result);
    }
    /**
     * 根据驾驶员名称,线路,日期返回驾驶员考勤汇总数据
     *
     * @param Request $request
     * @return void
     */
    public function driverDetailData(Request $request)
    {
        $params = $request->all();
        $query = $this->getQuery($params);
        $data = $query->orderBy('line')->orderBy('license_plate_num')->get()->toArray();
        //获取司机当天考勤汇总数据
        $driverData = DB::table('akbus_driver_attendance_collect')
            ->where('signDate', $params['date'])
            ->where('driver', $params['driver'])
            ->where('line', $params['line'])
            ->where('is_del', 0)
            ->get()
            ->toArray();
        $result = [
            'lists' => $data,
            'driverData' => $driverData,
        ];
        return response()->formatJson($result);
    }
    /**
     * 考勤记录修改
     *
     * @param Request $request
     * @return void
     */
    public function updateAttendanceStatus(Request $request)
    {
        $params = $request->all();

        if (isset($params['license_plate_num'])) {
            $params['license_plate_num'] = str_replace('陕G', '', $params['license_plate_num']);
        }
        if (isset($params['line'])) {
            $params['line'] = str_replace('路', '', $params['line']);
        }
        if (isset($params['date'])) {
            $params['sign_date'] = date('Y-m-d', strtotime($params['date']));
            unset($params['date']);
        }
        if (isset($params['driver'])) {
            $params['driver'] = str_replace(' ', '', $params['driver']);
        }
        if (isset($params['id']) && isset($params['normal_time']) && $params['mark'] == 'edit') {
            unset($params['mark']);
            $params['updated_at'] = date('Y-m-d H:i:s');
            $update = DB::table('akbus_attendance_collect')
                ->where('id', $params['id'])
                ->update($params);
            if ($update) {
                $result = $this->syncUpadate($params['id']);
                $message = $result ? '修改成功' : '修改失败';
            } else {
                $result = '';
                $message = '修改失败';
            }
        } elseif (!isset($params['id']) && isset($params['normal_time']) && $params['mark'] == 'add') {
            $start_sign_time = isset($params['start_sign_time']) ? $params['start_sign_time'] : '';
            $end_sign_time = isset($params['end_sign_time']) ? $params['end_sign_time'] : '';
            $insertData = [
                'line' => $params['line'],
                'driver' => $params['driver'],
                'sign_date' => $params['sign_date'],
                'license_plate_num' => $params['license_plate_num'],
                'normal_time' => $params['normal_time'],
                'start_sign_time' => $start_sign_time,
                'end_sign_time' => $end_sign_time,
                'created_at' => date('Y-m-d H:i:s')
            ];
            $id = DB::table('akbus_attendance_collect')->insertGetId($insertData);
            if ($id) {
                $result = $this->syncUpadate($id);
                $message = $result ? '添加成功' : '添加失败';
            } else {
                $result = '';
                $message = '添加失败';
            }
        } else {
            $result = '';
            $message = '意外错误,参数缺失!';
        }
        return response()->formatJson($result, $message);
    }
    /**
     * 汇总考勤中间表修改成功后同步判断是否需要修改车辆汇总与驾驶员汇总
     * @param $id 汇总中间表id
     */
    public function syncUpadate($id)
    {
        //根据id 获取车牌号,日期,驾驶员姓名
        $collectInfo = AttendanceCollect::query()->find($id)->toArray();
        //获取驾驶员汇总考勤时长
        $driverNt = $this->getNormalTime($collectInfo, 'driver');
        //判断驾驶员汇总考勤表有无对应记录 有则修改 无则添加
        $driverId = DB::table('akbus_driver_attendance_collect')
            ->where('driver', $collectInfo['driver'])
            ->whereDate('signDate', $collectInfo['sign_date'])
            ->where('is_del', 0)
            ->value('id');
        //获取车辆汇总考勤时长
        $busNt = $this->getNormalTime($collectInfo, 'bus');
        //判断车辆汇总考勤表有无对应记录 有则修改 无则添加
        $busId = DB::table('akbus_bus_attendance_collect')
            ->where('busNumber', $collectInfo['license_plate_num'])
            ->whereDate('signDate', $collectInfo['sign_date'])
            ->where('is_del', 0)
            ->value('id');
        //开启事务
        DB::beginTransaction();
        try {
            if ($driverId) {
                //有记录 进行修改
                DB::table('akbus_driver_attendance_collect')
                    ->where('id', $driverId)
                    ->update(['normalTime' => $driverNt, 'updated_at' => date('Y-m-d H:i:s')]);
            } else {
                //没有记录 进行添加
                $insertDriver = [
                    'normalTime' => $driverNt,
                    'line' => $collectInfo['line'],
                    'driver' => $collectInfo['driver'],
                    'signDate' => $collectInfo['sign_date'],
                    'created_at' => date('Y-m-d H:i:s'),
                ];
                DB::table('akbus_driver_attendance_collect')->insert($insertDriver);
            }
            if ($busId) {
                //有记录 进行修改
                DB::table('akbus_bus_attendance_collect')
                    ->where('id', $busId)
                    ->update(['normalTime' => $busNt, 'updated_at' => date('Y-m-d H:i:s')]);
            } else {
                //没有记录 进行添加
                $insertBus = [
                    'normalTime' => $busNt,
                    'line' => $collectInfo['line'],
                    'busNumber' => $collectInfo['license_plate_num'],
                    'signDate' => $collectInfo['sign_date'],
                    'created_at' => date('Y-m-d H:i:s'),
                ];
                DB::table('akbus_bus_attendance_collect')->insert($insertBus);
            }
            DB::commit();
            return true;
        } catch (\Throwable $th) {
            DB::rollBack();
            report($th);
            return false;
        }
    }
    /**
     *重新计算考勤
     */
    public function getNormalTime($collectInfo, $mark)
    {
        $query =  DB::table('akbus_attendance_collect')
            ->whereDate('sign_date', $collectInfo['sign_date'])
            ->where('is_del', 0);
        if ($mark == 'driver') {
            $query->where('driver', $collectInfo['driver']);
        }
        if ($mark == 'bus') {
            $query->where('license_plate_num', $collectInfo['license_plate_num']);
        }
        $data = $query->get()->toArray();
        $normalTime = array_sum(array_column($data, 'normal_time'));
        if ($normalTime >= 1) {
            $normalTime = 1;
        } else if ($normalTime < 1 && $normalTime >= 0.5) {
            $normalTime = 0.5;
        } else {
            $normalTime = 0;
        }
        return $normalTime;
    }
    /**
     * 修改考勤汇总记录
     *
     * @param Request $request
     * @return void
     */
    public function updateCollectData(Request $request)
    {
        $params = $request->all();
        if (isset($params['busNumber'])) {
            $params['busNumber'] = str_replace('陕G', '', $params['busNumber']);
        }
        if (isset($params['line'])) {
            $params['line'] = str_replace('路', '', $params['line']);
        }
        if (isset($params['date'])) {
            $params['signDate'] = date('Y-m-d', strtotime($params['date']));
            unset($params['date']);
        }
        if (isset($params['driver'])) {
            $params['driver'] = str_replace(' ', '', $params['driver']);
        }
        if (isset($params['type'])) {
            $type = $params['type'];
            unset($params['type']);
        }
        if (isset($params['id']) && $params['mark'] == 'edit' && isset($params['normalTime'])) {
            unset($params['mark']);
            $params['updated_at'] = date('Y-m-d H:i:s');
            switch ($type) {
                case 'bus':
                    unset($params['driver']);
                    $result = DB::table('akbus_bus_attendance_collect')
                        ->where('id', $params['id'])
                        ->update($params);
                    break;
                case 'driver':
                    unset($params['busNumber']);
                    $result = DB::table('akbus_driver_attendance_collect')
                        ->where('id', $params['id'])
                        ->update($params);
                    break;
                default:
                    break;
            }
            $message = $result ? '修改成功' : '修改失败';
        } elseif (!isset($params['id']) && $params['mark'] == 'add' && isset($params['normalTime'])) {

            switch ($type) {
                case 'bus':
                    $result = DB::table('akbus_bus_attendance_collect')
                        ->updateOrInsert(
                            ['line' => $params['line'], 'busNumber' => $params['busNumber'], 'signDate' => $params['signDate']],
                            ['created_at' => date('Y-m-d H:i:s'), 'normalTime' => $params['normalTime'], 'workHours' => $params['workHours']]
                        );
                    break;
                case 'driver':
                    $result = DB::table('akbus_driver_attendance_collect')
                        ->updateOrInsert(
                            ['line' => $params['line'], 'driver' => $params['driver'], 'signDate' => $params['signDate']],
                            ['created_at' => date('Y-m-d H:i:s'), 'normalTime' => $params['normalTime'], 'workHours' => $params['workHours']]
                        );
                    break;
                default:
                    break;
            }
            $message = $result ? '添加成功' : '添加失败';
        } else {
            $result = '';
            $message = '意外错误,参数缺失!';
        }
        return response()->formatJson($result, $message);
    }
    //转化数组顺序,符合钉钉接口需求(将所有打卡异常的车辆司机放在最前面)
    public function rebuildKeys($array)
    {
        if (!is_array($array)) {
            return $array;
        }
        $new_array = [];
        foreach ($array as $licensePlateNum => $drivers) {
            foreach ($drivers as $k => $driver) {
                if ($driver['status'] == '异常') {
                    $new_array[$licensePlateNum] = $drivers;
                }
            }
        }
        $new_array = $new_array + $array;
        $new_array = array_values($new_array);
        return $new_array;
    }
}
